using System;
using System.Collections.Generic;
using System.Collections;
using System.Dynamic;
using Lua4Mono;

using NUnit;
using NUnit.Framework;
using NUnit .Core;
using NUnit .Mocks;
using NUnit.Util;

namespace Test
{
	[TestFixture]
	public class MainClass
	{
	
		public static void Main ()
		{
			
			using(dynamic lua= new Lua(true))
			{
				lua.ShowText="Hello!";
				lua.DoString("print(ShowText)");
				
				
				
			}
			
			
			//准备一个静态方法的methodinfo
			Type type = typeof(MainClass);
			var met =type.GetMethod("Print");
			
			//准备一个字典集合
			Dictionary<string,int> kv = new Dictionary<string, int>();
			kv.Add("2",23);
			kv.Add("k",5);
			
			//准备一个数组
			object[] sst = new object[]{1,"b","c"};
			
			//开始使用
			//初始化一个lua对象
			using (Lua lua =new Lua())
			{
				dynamic dyLua=(dynamic)lua;
				//设置数组
				dyLua.sst=sst;
				
				//设置字典
				dyLua.kv=kv;
				
				//设置方法
				dyLua.p=met;
				
				//取出之前设置的字典,并打印设置的值
				var a =dyLua.kv;
				Console.WriteLine(a["k"]);
				
				//调用DoString来执行lua脚本
				object[] rtn =lua.DoString("c=p(sst[1],sst[2])");
				Console.WriteLine(rtn.Length);
				
				//调用注册到lua的方法
				dyLua.p(1,"2");
			
			}
						
		}
		
		public static string Print(string a,string b)
		{
				Console.WriteLine(a+":"+b);
			
			return a+":"+b;
		}
		
		public static string Print3(string a,string b,string c)
		{
				Console.WriteLine(a+":"+b+":"+c);
			
			return a+":"+b+":"+c;
		}
		
		public static string PrintVoid()
		{
			return "Void";
		}
		
		[Test]
		public void SetGetTest()
		{
			using (dynamic lua =new Lua())
			{
				lua.a=Int16.MaxValue;
				Assert.AreEqual(lua.a,Int16.MaxValue,"int16 max err");
				lua.a=Int16.MinValue;
				Assert.AreEqual(lua.a,Int16.MinValue,"int16 min err");
				
				lua.a=int.MaxValue;
				Assert.AreEqual(lua.a,int.MaxValue,"int max err");
				lua.a =int.MinValue;
				Assert.AreEqual(lua.a,int.MinValue,"int min err");
				
				lua.a=Int64.MaxValue;
				Assert.AreEqual(lua.a,Int64.MaxValue,"int64 max err");
				lua.a =Int64.MinValue ;
				Assert.AreEqual(lua.a,Int64.MinValue,"int64 min err");
				
				lua.a=double.MaxValue;
				Assert.AreEqual(lua.a,double.MaxValue,"double max err");
				lua.a=double.MinValue;
				Assert.AreEqual(lua.a,double.MinValue,"double min err");
				
				lua.a=decimal.MaxValue;
				Assert.AreEqual(lua.a,decimal.MaxValue,"dec max err");
				lua.a=decimal.MinValue;
				Assert.AreEqual(lua.a,decimal.MinValue,"dec min err");
				
				lua.a =null;
				Assert .AreEqual(lua.a,null,"null err");
				
				lua.a="hello world";
				Assert.AreEqual(lua.a,"hello world","string err");
				
				lua.a =string.Empty;
				Assert.AreEqual(lua.a,string.Empty,"string empty err");
				
				//lua 没有char类型,所以返回值只能是string
				lua.a='a';
				Assert.AreEqual(lua.a,"a","char err");
				
				Dictionary<string,object> kv = new Dictionary<string, object>();
				kv.Add("int",int.MaxValue);
				kv.Add("double",double.MaxValue);
				kv.Add("string","hello");
				
				lua.a =kv;
				var rtn =lua.a;
				foreach(string key in kv.Keys)
				{
					Assert.AreEqual(kv[key],rtn[key],key+" err");
				}
				
				object[] objs= new object[]{1,1.1M,12.22f,"K.O"};
				lua.a=objs;
				var arr=lua.a;
				for(int i=0;i<objs.Length;i++)
				{
					Assert.AreEqual(objs[i],arr[i],i+" err");
				}
				
			}
		}
		
		[Test]
		public void methodCall()
		{
			Type type = typeof(MainClass);
			var met =type.GetMethod("Print");
			var met2= type.GetMethod("Print3");
			var met3= type.GetMethod("PrintVoid");
			using(dynamic lua= new Lua())
			{
				lua.p=met;
				var rtn =lua.p("1","2")[0];
				Assert.AreEqual(rtn,Print("1","2"),"print err");
				
				lua.p=met2;
				var rtn2=lua.p("3","2","1")[0];
				Assert.AreEqual(rtn2,Print3("3","2","1"),"print3 err");
				
				lua.p =met3;
				var rtn3 =lua.p()[0];
				Assert.AreEqual(rtn3,PrintVoid(),"void err");
			}
		}
		[Test]
		public void doStringTest()
		{
			Type type = typeof(MainClass);
			var met =type.GetMethod("Print");
			string luaSrc1="a=100";
			string luasrc2="return p(1,2)";
			
			using(Lua lua= new Lua())
			{
				dynamic d=lua;
				lua.DoString(luaSrc1);
				
				Assert.AreEqual(d.a,100,"1 error");
				d.p=met;
				var rtn =lua.DoString(luasrc2)[0];
				Assert.AreEqual(rtn,Print("1","2"),"print err");
			}
		}
	}
}
